#ifndef SLIST_H
#define SLIT_H

template<class T>
class slist{
public:
	typedef T value_type;
	typedef ptrdiff_t difference_type;
	typedef T& reference;
	typedef T* pointer;
	
	//todo 
	slist():first(0),count(0){}
	
	~slist(){
		std::cout<<"\ninvoking slist descructor\n";
		//first to end
		ListElement* f=first;
		while(f!=NULL){
			ListElement* tmp=f;
			f=f->next;
			delete tmp;
		}
	}
	
	void push_front(const T& ele){
		first=new ListElement(ele,first);
	}
	
private:
	struct ListElement{
		T data;
		ListElement* next;
		ListElement(const T& datam,ListElement* p):data(datam),next(p){}
	};
	ListElement* first;
	size_t count;

public:
	class iterator{
	public:
		typedef std::forward_iterator_tag iterator_category;
		typedef T value_type;
		typedef T* pointer;
		typedef T& reference;
		typedef size_t size_type;
		typedef ptrdiff_t difference_type;
		
		iterator(ListElement* init=0):current(init)
		{}
		
		const T& operator*() const{
			return current->data;
		}
		
		iterator& operator++(){
			if(current)
				current=current->next;
			return *this;
		}
		
		iterator operator++(int){
			iterator temp=*this;
			++*this;
			return temp;
		}
		
		
		bool operator==(const iterator& x)const{
			return current==x.current;
		}
		
		bool operator!=(const iterator& x)const{
			return current!=x.current;
		}
		
	private:
		ListElement* current;	
	};
	
	iterator begin() const {return iterator(first);}
	iterator end() const{return iterator();}
	
	iterator erase(iterator p){
		//List*Element previous
		ListElement* f=first;
		ListElement* pre=NULL;
		while(f!=NULL && f->data!=*p){
			pre=f;
			f=f->next;			
		}
		assert(f->data==*p);
		if(pre==NULL){
			first=f->next;
			delete f;
			return first;
		}else{
			pre->next=f->next;
			delete f;
			return pre->next;
		}
	}
	
};

template<class iterator>
int operator-(iterator first,iterator second){
	int count=0;
	while(first!=second && first!=iterator()){
		count++;
		first++;
	}
	assert(first==second);
	return count;
}


#endif